package com.xishu.foodpanda;

import com.xishu.entity.foodpanda.Product;
import com.xishu.entity.shop.Item;
import com.xishu.entity.shop.ItemDetail;
import com.xishu.entity.shop.SetMenuOneItem;
import com.xishu.service.ItemService;
import com.xishu.to.foodpanda.FoodPandaAnnotation;
import com.xishu.to.foodpanda.FoodPandaBase;
import com.xishu.to.foodpanda.FoodPandaZhEn;
import com.xishu.util.ClassUtil;
import com.xishu.util.CollectionUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

public class FoodPandaBaseService {
    public static final String TOPPING = "Topping";
    public static final String PRODUCT = "Product";

    public static final String IMAGE = "Image";

    private static Logger logger = LoggerFactory.getLogger(FoodPandaBaseService.class);

    /**
     * 将一个对象转化成map对象，并且按照foodpanda格式
     *
     * @param object
     * @return
     */
    public static Map beanToMap(Object object) throws Exception {
        Map<String, Object> map = new LinkedHashMap<>();
        List<Field> fields = ClassUtil.getAllField(object, "serialVersionUID");
        List<Field> fieldList = fields.stream().filter(f -> {
            try {
                return f.get(object) != null;
            } catch (Exception e) {
                logger.error("e", e);
                return false;
            }
        }).collect(Collectors.toList());

        //这里所有的字段均不为空
        for (Field f : fieldList) {
            FoodPandaAnnotation annotation = f.getAnnotation(FoodPandaAnnotation.class);
            if (annotation != null && annotation.fieldToString()) {
                map.put(f.getName(), f.get(object).toString());
            } else if (annotation != null && annotation.addId()) {
                FoodPandaBase fieldValue = (FoodPandaBase) f.get(object);
                LinkedHashMap<String, Object> valueMap = new LinkedHashMap<>();
                valueMap.put(fieldValue.id, beanToMap(fieldValue));
                map.put(f.getName(), valueMap);
            } else if (f.getType().getName().equals("java.util.List") && annotation != null && annotation.listToObject()) {
                //如果是List,需要将转化成
                /**
                 *  "pd01": {
                 *             "id": "pd01",
                 *             "type": "Product"
                 *           },
                 */
                List<? extends FoodPandaBase> fieldValue = (List<? extends FoodPandaBase>) f.get(object);
                List<Map> valueListMap = fieldValue.stream().map(value -> {
                    try {
                        return addIdMap(value);
                    } catch (Exception e) {
                        logger.error("e", e);
                        return null;
                    }
                }).filter(p -> p != null).collect(Collectors.toList());

                LinkedHashMap<String, Object> valueMap = new LinkedHashMap<>();
                valueListMap.forEach(value -> {
                    valueMap.putAll(value);
                });

                map.put(f.getName(), valueMap);
            } else {
                //需要再按照foodpanda的格式转化一次
                if (StringUtils.equals(f.getType().getName(), FoodPandaZhEn.class.getName())) {
                    Map<String, Object> zhEnMap = new LinkedHashMap<>();
                    FoodPandaZhEn foodPandaZhEn = (FoodPandaZhEn) f.get(object);
                    zhEnMap.put("default", foodPandaZhEn.getEn_HK());
                    zhEnMap.put("zh_HK", foodPandaZhEn.getZh_HK());
                    zhEnMap.put("en_HK", foodPandaZhEn.getEn_HK());
                    map.put(f.getName(), zhEnMap);
                } else if (f.get(object).getClass().getTypeName().contains("com.xishu.entity.foodpanda")) {
                    FoodPandaBase foodPandaBase = (FoodPandaBase) f.get(object);
                    map.put(f.getName(), CollectionUtil.getInstance().beanToMap(foodPandaBase));
                } else {
                    map.put(f.getName(), f.get(object));
                }
            }
        }

        return map;
    }


    /**
     * 按照foodpanda的格式，添加ID，并将对象转化成map
     *
     * @param object
     * @param <T>
     * @return
     */
    public static <T extends FoodPandaBase> Map<String, Object> addIdMap(T object) throws Exception {
        HashMap<String, Object> map = new HashMap<>();
        map.put(object.id, beanToMap(object));
        return map;
    }

    /**
     * 生成Topping下面的每一个菜的ID
     *
     * @param toppingId
     * @param nameAndPriceId
     * @return
     */
    public static String generateToppingProductId(Long toppingId, Long nameAndPriceId) {
        return String.format("topping.%s.product.%s", toppingId, nameAndPriceId);
    }

    /**
     * 产生ProductId
     * 全局唯一
     *
     * @param menuId
     * @param categoryId
     * @param productId
     * @return
     */
    public static String generateProductId(Long menuId, Long categoryId, Long productId) {
        return String.format("menu.%s.category.%s.item.%s", menuId, categoryId, productId);
    }

    /**
     * 产生一个细节的ID
     *
     * @param productId
     * @param itemDetailId
     * @return
     */
    public static String generateToppingId(Long productId, Long itemDetailId) {
        return String.format("product.%s.topping.%s", productId, itemDetailId);
    }

    /**
     * 产生一个细节的ID
     *
     * @param productId
     * @param itemId
     * @param detailId
     * @return
     */
    public static String generateFixItemDetailToppingId(Long productId, Long itemId, Long detailId, Integer index) {
        return String.format("setmenu.product.%s.item.%s.topping.%s.index.%s", productId, itemId, detailId, index);
    }

    /**
     * 生成一个variant ID
     *
     * @param productId
     * @return
     */
    public static String generateVariantId(Long menuId, Long productId) {
        return String.format("menu.%s.product.%s.variant.%s", menuId, productId, productId);
    }

    /**
     * 生成套餐下面的每一个菜的ID
     *
     * @param toppingId
     * @param itemId
     * @return
     */
    public static String generateSetMenuToppingProductId(Long toppingId, Long itemId) {
        return String.format("setmenu.topping.%s.product.%s", toppingId, itemId);
    }

    /**
     * 固定菜下面的菜的ID
     *
     * @param toppingId
     * @param itemId
     * @param index
     * @return
     */
    public static String generateSetMenuToppingProductId(Long toppingId, Long itemId, Number index) {
        return String.format("setmenu.fix.topping.%s.product.%s.%s", toppingId, itemId, index);
    }

    /**
     * 生成固定菜下面的菜的细节ID
     *
     * @param toppingId
     * @param itemId
     * @param detailId
     * @param
     * @return
     */
    public static String generateFixSetMenuItemDetailProductId(Long toppingId, Long itemId, Long detailId, Long nameId, Integer index) {
        return String.format("setmenu.%s.fix.item.%s.detail.%s.name.%s.index.%s", toppingId, itemId, detailId, nameId, index);
    }

    /**
     * 普通菜并且有细节
     *
     * @param product
     * @return
     */
    public static boolean isCommonProductHasDetail(Product product) {
        //套餐不满足
        if (BooleanUtils.isTrue(product.getSetMenu())) {
            return false;
        }

        List<ItemDetail> itemDetailList = product.getItemDetailList();
        //没有细节
        if (CollectionUtils.isEmpty(itemDetailList)) {
            return false;
        }

        //如果细节有，但是只有一行，并且没有名称，也忽略
        if (itemDetailList.size() == 1) {
            ItemDetail itemDetail = itemDetailList.get(0);
            if (StringUtils.isEmpty(itemDetail.getName_zh()) && StringUtils.isEmpty(itemDetail.getName_en())) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取套餐里面的固定菜
     *
     * @param setMenuOneItem
     * @return
     */
    public static Optional<Item> getSetMenuItem(SetMenuOneItem setMenuOneItem) {
        if (setMenuOneItem == null) {
            logger.info("set menu is null");
            return Optional.empty();
        }

        if (setMenuOneItem.getFixed() == null || !setMenuOneItem.getFixed()) {
            logger.info("set menu not fix");
            return Optional.empty();
        }

        List<Item> itemList = setMenuOneItem.getItemList();
        if (CollectionUtils.isEmpty(itemList)) {
            logger.info("item list is empty");
            return Optional.empty();
        }

        Long itemId = itemList.get(0).getId();
        try {
            Item item = ItemService.getInstance().findItem(itemId);
            Item itemClone = (Item) ClassUtil.clone(item);
            //价格从foodpanda里面读取，剩下的配置从以前的菜里面读取
            itemClone.setSetMenuAddPrice(itemList.get(0).getSetMenuAddPrice());
            return Optional.of(itemClone);
        } catch (Exception e) {
            logger.error("e", e);
            return Optional.empty();
        }
    }

    /**
     * 获取固定菜的单个价格
     *
     * @param setMenuOneItem
     * @return
     */
    public static Double getFixItemPrice(SetMenuOneItem setMenuOneItem) {
        Optional<Item> itemOptional = getSetMenuItem(setMenuOneItem);

        if (!itemOptional.isPresent()) {
            return 0d;
        }

        Item item = itemOptional.get();

        if (item.getSetMenuAddPrice() == null) {
            logger.info("do not have the price");
            return 0d;
        }

        return item.getSetMenuAddPrice() / setMenuOneItem.getItemNumber();
    }
}
